In [1]:
import os
import math
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import plotly.express as px
import plotly.graph_objects as go
import pickle
In [2]:
%%time
if os.path.exists('contagem_geral.pickle'):
print('O arquivo de contagem geral existe, carregando...')
with open('contagem_geral.pickle', 'rb') as file:
contagem_geral = pickle.load(file)
print('Importação concluída!\n')
else:
print('Erro! Antes de executar a análise, execute o Notebook 01 de Carga.')
O arquivo de contagem geral existe, carregando... Importação concluída! CPU times: user 1.47 s, sys: 562 ms, total: 2.04 s Wall time: 2.04 s
In [3]:
contagem_geral.head()
Out[3]:
| senha | ocorrencias | caracteres | caracteres_unicos | ocorrencias_percentuais | |
|---|---|---|---|---|---|
| 0 | 123456 | 20963035 | 6 | 6 | 0.050208 |
| 1 | 12345 | 7030768 | 5 | 5 | 0.016839 |
| 2 | 12345678 | 3521408 | 8 | 8 | 0.008434 |
| 3 | 111111 | 2906365 | 6 | 1 | 0.006961 |
| 4 | 1234567 | 2363539 | 7 | 7 | 0.005661 |
In [4]:
contagem_geral.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 24140087 entries, 0 to 24140086 Data columns (total 5 columns): # Column Dtype --- ------ ----- 0 senha object 1 ocorrencias int64 2 caracteres int64 3 caracteres_unicos int64 4 ocorrencias_percentuais float64 dtypes: float64(1), int64(3), object(1) memory usage: 920.9+ MB
In [5]:
contagem_geral.describe(include='number')
Out[5]:
| ocorrencias | caracteres | caracteres_unicos | ocorrencias_percentuais | |
|---|---|---|---|---|
| count | 2.414009e+07 | 2.414009e+07 | 2.414009e+07 | 2.414009e+07 |
| mean | 1.729590e+01 | 7.552672e+00 | 5.390836e+00 | 4.142487e-08 |
| std | 4.729153e+03 | 5.999113e-01 | 9.879169e-01 | 1.132665e-05 |
| min | 1.000000e+00 | 4.000000e+00 | 1.000000e+00 | 2.395069e-09 |
| 25% | 1.000000e+00 | 7.000000e+00 | 5.000000e+00 | 2.395069e-09 |
| 50% | 2.000000e+00 | 8.000000e+00 | 5.000000e+00 | 4.790138e-09 |
| 75% | 4.000000e+00 | 8.000000e+00 | 6.000000e+00 | 9.580277e-09 |
| max | 2.096304e+07 | 8.000000e+00 | 8.000000e+00 | 5.020792e-02 |
In [6]:
amostra = contagem_geral.sample(100_000)
Vamos entender a distribuição das senhasm no sentido de saber se há muitas senhas pouco usadas e poucas senhas muito usadas.
Se isso se confirmar, podemos, por exemplo, estudar apenas as senhas que apareçam N vezes ou mais.
In [7]:
fig = px.box(amostra, y='ocorrencias', hover_data='senha', height=600, width=600)
fig.show()
A grande maioria das senhas (mais de 75% de toda a base) aparece menos de 10 vezes (ao menos na amostra).
Utilizaremos uma quantidade de senhas que permita capturar as entradas relevantes, porém ainda com uma quantidade significativa, acima de 100 mil de entradas.
In [8]:
contagem_selecionada = contagem_geral.query('ocorrencias > 1000')
print(contagem_selecionada.info())
contagem_selecionada.describe()
<class 'pandas.core.frame.DataFrame'> Index: 50296 entries, 0 to 50295 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 senha 50296 non-null object 1 ocorrencias 50296 non-null int64 2 caracteres 50296 non-null int64 3 caracteres_unicos 50296 non-null int64 4 ocorrencias_percentuais 50296 non-null float64 dtypes: float64(1), int64(3), object(1) memory usage: 2.3+ MB None
Out[8]:
| ocorrencias | caracteres | caracteres_unicos | ocorrencias_percentuais | |
|---|---|---|---|---|
| count | 5.029600e+04 | 50296.000000 | 50296.000000 | 50296.000000 |
| mean | 4.269271e+03 | 6.740317 | 4.667667 | 0.000010 |
| std | 1.035166e+05 | 1.155383 | 1.187251 | 0.000248 |
| min | 1.001000e+03 | 4.000000 | 1.000000 | 0.000002 |
| 25% | 1.355000e+03 | 6.000000 | 4.000000 | 0.000003 |
| 50% | 2.010000e+03 | 6.000000 | 5.000000 | 0.000005 |
| 75% | 3.576000e+03 | 8.000000 | 5.000000 | 0.000009 |
| max | 2.096304e+07 | 8.000000 | 8.000000 | 0.050208 |
In [9]:
fig = px.box(contagem_selecionada, y='ocorrencias', hover_data='senha', height=600, width=600)
fig.show()
In [10]:
contagem_selecionada.head(100)
Out[10]:
| senha | ocorrencias | caracteres | caracteres_unicos | ocorrencias_percentuais | |
|---|---|---|---|---|---|
| 0 | 123456 | 20963035 | 6 | 6 | 0.050208 |
| 1 | 12345 | 7030768 | 5 | 5 | 0.016839 |
| 2 | 12345678 | 3521408 | 8 | 8 | 0.008434 |
| 3 | 111111 | 2906365 | 6 | 1 | 0.006961 |
| 4 | 1234567 | 2363539 | 7 | 7 | 0.005661 |
| ... | ... | ... | ... | ... | ... |
| 95 | 159159 | 82353 | 6 | 3 | 0.000197 |
| 96 | 123457 | 81928 | 6 | 6 | 0.000196 |
| 97 | 565656 | 81926 | 6 | 2 | 0.000196 |
| 98 | 123098 | 80919 | 6 | 6 | 0.000194 |
| 99 | 123987 | 80804 | 6 | 6 | 0.000194 |
100 rows × 5 columns
In [11]:
fig = px.violin(contagem_selecionada, y='caracteres_unicos', x= 'caracteres', box=False, height=600, width=1200)
fig.show()
In [12]:
senhas_4_digitos = contagem_selecionada.query('caracteres == 4')
senhas_5_digitos = contagem_selecionada.query('caracteres == 5')
senhas_6_digitos = contagem_selecionada.query('caracteres == 6')
senhas_7_digitos = contagem_selecionada.query('caracteres == 7')
senhas_8_digitos = contagem_selecionada.query('caracteres == 8')
In [13]:
rotulos = ['senhas_4_digitos', 'senhas_5_digitos', 'senhas_6_digitos', 'senhas_7_digitos', 'senhas_8_digitos']
tamanhos = [len(senhas_4_digitos), len(senhas_5_digitos), len(senhas_6_digitos), len(senhas_7_digitos), len(senhas_8_digitos)]
fig = px.bar(y=tamanhos, x=rotulos, height=600, width=1200)
fig.show()
Senhas de 4 Dígitos¶
Vamos analisar, para cada uma das 4 posições, qual a frequência observada dos 10 possíveis dígitos.
Para isso, vamos considerar os dígitos da esquerda para a direita.
Por exemplo, no caso de 1234:
- Primeiro: 1
- Segundo: 2
- Terceiro: 3
- Quarto: 4
In [14]:
contador = 0
print('-' * 70, '\n\n')
for pos in ['primeiro', 'segundo', 'terceiro', 'quarto']:
digito = []
digito_contagem = {}
for i in senhas_4_digitos['senha'].values:
digito.append(i[contador])
for i in set(digito):
digito_contagem[i] = digito.count(i)
digito_contagem = dict(sorted(digito_contagem.items()))
print(f'Frequência dos dígitos no {pos} dígito:\n', digito_contagem)
fig = px.bar(x=digito_contagem.keys(), y=digito_contagem.values(), height=600, width=1200)
fig.show()
print('-' * 70, '\n\n')
contador = contador + 1
----------------------------------------------------------------------
Frequência dos dígitos no primeiro dígito:
{'0': 310, '1': 799, '2': 511, '3': 172, '4': 110, '5': 110, '6': 56, '7': 85, '8': 60, '9': 52}
----------------------------------------------------------------------
Frequência dos dígitos no segundo dígito:
{'0': 201, '1': 283, '2': 279, '3': 255, '4': 214, '5': 283, '6': 184, '7': 173, '8': 198, '9': 195}
----------------------------------------------------------------------
Frequência dos dígitos no terceiro dígito:
{'0': 369, '1': 358, '2': 347, '3': 186, '4': 139, '5': 174, '6': 157, '7': 166, '8': 206, '9': 163}
----------------------------------------------------------------------
Frequência dos dígitos no quarto dígito:
{'0': 247, '1': 278, '2': 229, '3': 216, '4': 197, '5': 239, '6': 207, '7': 200, '8': 223, '9': 229}
----------------------------------------------------------------------
Senhas de 5 Dígitos¶
In [15]:
contador = 0
print('-' * 70, '\n\n')
for pos in ['primeiro', 'segundo', 'terceiro', 'quarto', 'quinto']:
digito = []
digito_contagem = {}
for i in senhas_5_digitos['senha'].values:
digito.append(i[contador])
for i in set(digito):
digito_contagem[i] = digito.count(i)
digito_contagem = dict(sorted(digito_contagem.items()))
print(f'Frequência dos dígitos no {pos} dígito:\n', digito_contagem)
fig = px.bar(x=digito_contagem.keys(), y=digito_contagem.values(), height=600, width=1200)
fig.show()
print('-' * 70, '\n\n')
contador = contador + 1
----------------------------------------------------------------------
Frequência dos dígitos no primeiro dígito:
{'0': 120, '1': 557, '2': 354, '3': 68, '4': 33, '5': 29, '6': 28, '7': 41, '8': 24, '9': 33}
----------------------------------------------------------------------
Frequência dos dígitos no segundo dígito:
{'0': 176, '1': 179, '2': 206, '3': 123, '4': 93, '5': 123, '6': 78, '7': 77, '8': 86, '9': 146}
----------------------------------------------------------------------
Frequência dos dígitos no terceiro dígito:
{'0': 512, '1': 361, '2': 61, '3': 76, '4': 29, '5': 35, '6': 41, '7': 51, '8': 55, '9': 66}
----------------------------------------------------------------------
Frequência dos dígitos no quarto dígito:
{'0': 126, '1': 184, '2': 238, '3': 103, '4': 101, '5': 112, '6': 100, '7': 110, '8': 104, '9': 109}
----------------------------------------------------------------------
Frequência dos dígitos no quinto dígito:
{'0': 97, '1': 140, '2': 74, '3': 141, '4': 23, '5': 72, '6': 32, '7': 126, '8': 362, '9': 220}
----------------------------------------------------------------------
Senhas de 6 Dígitos¶
In [16]:
contador = 0
print('-' * 70, '\n\n')
for pos in ['primeiro', 'segundo', 'terceiro', 'quarto', 'quinto', 'sexto']:
digito = []
digito_contagem = {}
for i in senhas_6_digitos['senha'].values:
digito.append(i[contador])
for i in set(digito):
digito_contagem[i] = digito.count(i)
digito_contagem = dict(sorted(digito_contagem.items()))
print(f'Frequência dos dígitos no {pos} dígito:\n', digito_contagem)
fig = px.bar(x=digito_contagem.keys(), y=digito_contagem.values(), height=600, width=1200)
fig.show()
print('-' * 70, '\n\n')
contador = contador + 1
----------------------------------------------------------------------
Frequência dos dígitos no primeiro dígito:
{'0': 5374, '1': 8940, '2': 6798, '3': 1178, '4': 243, '5': 317, '6': 221, '7': 388, '8': 663, '9': 223}
----------------------------------------------------------------------
Frequência dos dígitos no segundo dígito:
{'0': 2436, '1': 2792, '2': 2820, '3': 2331, '4': 2223, '5': 2427, '6': 2044, '7': 1999, '8': 2093, '9': 3180}
----------------------------------------------------------------------
Frequência dos dígitos no terceiro dígito:
{'0': 13453, '1': 6676, '2': 673, '3': 485, '4': 281, '5': 395, '6': 438, '7': 636, '8': 697, '9': 611}
----------------------------------------------------------------------
Frequência dos dígitos no quarto dígito:
{'0': 2359, '1': 3614, '2': 3597, '3': 2056, '4': 2002, '5': 2118, '6': 1910, '7': 1843, '8': 1914, '9': 2932}
----------------------------------------------------------------------
Frequência dos dígitos no quinto dígito:
{'0': 4174, '1': 1578, '2': 1162, '3': 435, '4': 340, '5': 726, '6': 3087, '7': 4226, '8': 4378, '9': 4239}
----------------------------------------------------------------------
Frequência dos dígitos no sexto dígito:
{'0': 2575, '1': 2380, '2': 2277, '3': 2349, '4': 2190, '5': 2459, '6': 2468, '7': 2350, '8': 2494, '9': 2803}
----------------------------------------------------------------------
Senhas de 7 Dígitos¶
In [17]:
contador = 0
print('-' * 70, '\n\n')
for pos in ['primeiro', 'segundo', 'terceiro', 'quarto', 'quinto', 'sexto', 'setimo']:
digito = []
digito_contagem = {}
for i in senhas_7_digitos['senha'].values:
digito.append(i[contador])
for i in set(digito):
digito_contagem[i] = digito.count(i)
digito_contagem = dict(sorted(digito_contagem.items()))
print(f'Frequência dos dígitos no {pos} dígito:\n', digito_contagem)
fig = px.bar(x=digito_contagem.keys(), y=digito_contagem.values(), height=600, width=1200)
fig.show()
print('-' * 70, '\n\n')
contador = contador + 1
----------------------------------------------------------------------
Frequência dos dígitos no primeiro dígito:
{'0': 187, '1': 683, '2': 339, '3': 122, '4': 56, '5': 89, '6': 55, '7': 103, '8': 42, '9': 70}
----------------------------------------------------------------------
Frequência dos dígitos no segundo dígito:
{'0': 190, '1': 357, '2': 266, '3': 145, '4': 127, '5': 191, '6': 101, '7': 102, '8': 102, '9': 165}
----------------------------------------------------------------------
Frequência dos dígitos no terceiro dígito:
{'0': 564, '1': 327, '2': 185, '3': 177, '4': 65, '5': 113, '6': 63, '7': 80, '8': 86, '9': 86}
----------------------------------------------------------------------
Frequência dos dígitos no quarto dígito:
{'0': 143, '1': 405, '2': 229, '3': 159, '4': 181, '5': 146, '6': 126, '7': 130, '8': 135, '9': 92}
----------------------------------------------------------------------
Frequência dos dígitos no quinto dígito:
{'0': 71, '1': 750, '2': 99, '3': 121, '4': 60, '5': 160, '6': 66, '7': 85, '8': 42, '9': 292}
----------------------------------------------------------------------
Frequência dos dígitos no sexto dígito:
{'0': 87, '1': 102, '2': 183, '3': 73, '4': 100, '5': 111, '6': 95, '7': 70, '8': 218, '9': 707}
----------------------------------------------------------------------
Frequência dos dígitos no setimo dígito:
{'0': 145, '1': 183, '2': 94, '3': 150, '4': 67, '5': 123, '6': 100, '7': 132, '8': 438, '9': 314}
----------------------------------------------------------------------
Senhas de 8 Dígitos¶
In [18]:
contador = 0
print('-' * 70, '\n\n')
for pos in ['primeiro', 'segundo', 'terceiro', 'quarto', 'quinto', 'sexto', 'setimo', 'oitavo']:
digito = []
digito_contagem = {}
for i in senhas_8_digitos['senha'].values:
digito.append(i[contador])
for i in set(digito):
digito_contagem[i] = digito.count(i)
digito_contagem = dict(sorted(digito_contagem.items()))
print(f'Frequência dos dígitos no {pos} dígito:\n', digito_contagem)
fig = px.bar(x=digito_contagem.keys(), y=digito_contagem.values(), height=600, width=1200)
fig.show()
print('-' * 70, '\n\n')
contador = contador + 1
----------------------------------------------------------------------
Frequência dos dígitos no primeiro dígito:
{'0': 4868, '1': 8190, '2': 5982, '3': 992, '4': 122, '5': 147, '6': 76, '7': 110, '8': 83, '9': 83}
----------------------------------------------------------------------
Frequência dos dígitos no segundo dígito:
{'0': 1903, '1': 2339, '2': 2147, '3': 1941, '4': 1865, '5': 2010, '6': 1758, '7': 1753, '8': 1782, '9': 3155}
----------------------------------------------------------------------
Frequência dos dígitos no terceiro dígito:
{'0': 12972, '1': 4515, '2': 359, '3': 320, '4': 208, '5': 229, '6': 194, '7': 242, '8': 1228, '9': 386}
----------------------------------------------------------------------
Frequência dos dígitos no quarto dígito:
{'0': 1724, '1': 3114, '2': 3140, '3': 1845, '4': 1858, '5': 1867, '6': 1784, '7': 1800, '8': 1826, '9': 1695}
----------------------------------------------------------------------
Frequência dos dígitos no quinto dígito:
{'0': 538, '1': 15047, '2': 3947, '3': 240, '4': 144, '5': 289, '6': 118, '7': 120, '8': 109, '9': 101}
----------------------------------------------------------------------
Frequência dos dígitos no sexto dígito:
{'0': 3934, '1': 529, '2': 602, '3': 359, '4': 260, '5': 330, '6': 293, '7': 207, '8': 262, '9': 13877}
----------------------------------------------------------------------
Frequência dos dígitos no setimo dígito:
{'0': 4190, '1': 814, '2': 629, '3': 246, '4': 230, '5': 311, '6': 2551, '7': 3867, '8': 3908, '9': 3907}
----------------------------------------------------------------------
Frequência dos dígitos no oitavo dígito:
{'0': 2129, '1': 2124, '2': 2033, '3': 1979, '4': 1960, '5': 2068, '6': 2042, '7': 2040, '8': 2180, '9': 2098}
----------------------------------------------------------------------
In [ ]: